package formatter

import (
    "fmt"
    "strings"
    "time"
    "unicode/utf8"

    "sysinfo/internal/types"
)

// FormatTable 以表格形式格式化系统信息（纯文本，不含颜色）
func FormatTable(info *types.SystemInfo) string {
    var sb strings.Builder

    sb.WriteString(fmt.Sprintf("时间戳: %s\n\n", info.Timestamp.Format("2006-01-02 15:04:05")))

    // 系统信息
    if info.System != nil {
        sb.WriteString("系统信息\n")
        headers := []string{"字段", "值"}
        rows := [][]string{
            {"主机名", info.System.Hostname},
            {"操作系统", info.System.OS},
            {"平台", fmt.Sprintf("%s %s", info.System.Platform, info.System.PlatformVersion)},
            {"平台系列", info.System.PlatformFamily},
            {"内核", fmt.Sprintf("%s (%s)", info.System.KernelVersion, info.System.KernelArch)},
            {"运行时间", info.System.UptimeFormatted},
            {"进程数", fmt.Sprintf("%d", info.System.Procs)},
        }
        writeTable(&sb, headers, rows)
        sb.WriteString("\n")
    }

    // CPU 信息
    if info.CPU != nil {
        sb.WriteString("CPU信息\n")
        headers := []string{"字段", "值"}
        rows := [][]string{
            {"型号", info.CPU.ModelName},
            {"制造商", info.CPU.Vendor},
            {"物理核心", fmt.Sprintf("%d", info.CPU.Cores)},
            {"逻辑CPU", fmt.Sprintf("%d", info.CPU.LogicalCPUs)},
            {"频率", fmt.Sprintf("%.2f MHz", info.CPU.MHz)},
        }
        if info.CPU.CacheSize > 0 {
            rows = append(rows, []string{"缓存大小", fmt.Sprintf("%d KB", info.CPU.CacheSize)})
        }
        if info.CPU.Microcode != "" {
            rows = append(rows, []string{"微码", info.CPU.Microcode})
        }
        if info.CPU.LoadAvg != nil {
            rows = append(rows, []string{"负载平均值", fmt.Sprintf("%.2f, %.2f, %.2f", info.CPU.LoadAvg.Load1, info.CPU.LoadAvg.Load5, info.CPU.LoadAvg.Load15)})
        }
        writeTable(&sb, headers, rows)

        // 核心使用率
        if len(info.CPU.Usage) > 0 {
            sb.WriteString("\nCPU核心使用率\n")
            headers := []string{"核心", "使用率(%)"}
            var usageRows [][]string
            max := len(info.CPU.Usage)
            if max > 32 {
                max = 32
            }
            for i := 0; i < max; i++ {
                usageRows = append(usageRows, []string{fmt.Sprintf("%d", i), fmt.Sprintf("%.2f", info.CPU.Usage[i])})
            }
            writeTable(&sb, headers, usageRows)
        }
        sb.WriteString("\n")
    }

    // 内存信息
    if info.Memory != nil {
        sb.WriteString("内存信息\n")
        headers := []string{"字段", "值"}
        rows := [][]string{
            {"总量", info.Memory.TotalFormatted},
            {"已用", fmt.Sprintf("%s (%.2f%%)", info.Memory.UsedFormatted, info.Memory.UsedPercent)},
            {"可用", info.Memory.FreeFormatted},
        }
        if info.Memory.SwapTotal > 0 {
            rows = append(rows, []string{"交换区总量", formatBytes(info.Memory.SwapTotal)})
            rows = append(rows, []string{"交换区已用", fmt.Sprintf("%s (%.2f%%)", formatBytes(info.Memory.SwapUsed), info.Memory.SwapPercent)})
        }
        writeTable(&sb, headers, rows)
        sb.WriteString("\n")
    }

    // 网络接口
    if info.Network != nil && len(info.Network.Interfaces) > 0 {
        sb.WriteString("网络接口\n")
        headers := []string{"名称", "MAC", "IP地址", "发送", "接收"}
        var rows [][]string
        for _, iface := range info.Network.Interfaces {
            ipStr := strings.Join(iface.Addresses, ", ")
            sendStr := ""
            recvStr := ""
            if iface.BytesSent > 0 {
                sendStr = formatBytes(iface.BytesSent)
            }
            if iface.BytesRecv > 0 {
                recvStr = formatBytes(iface.BytesRecv)
            }
            rows = append(rows, []string{iface.Name, iface.HardwareAddr, ipStr, sendStr, recvStr})
        }
        writeTable(&sb, headers, rows)
        sb.WriteString("\n")
    }

    // 进程信息（Top）
    if info.Processes != nil {
        // 内存排行
        if len(info.Processes.TopByMemory) > 0 {
            sb.WriteString("进程内存排行\n")
            headers := []string{"名称", "PID", "内存(MB)", "内存(%)"}
            var rows [][]string
            max := len(info.Processes.TopByMemory)
            if max > 10 { max = 10 }
            for i := 0; i < max; i++ {
                p := info.Processes.TopByMemory[i]
                rows = append(rows, []string{p.Name, fmt.Sprintf("%d", p.PID), fmt.Sprintf("%d", p.MemoryMB), fmt.Sprintf("%.2f", p.MemoryPercent)})
            }
            writeTable(&sb, headers, rows)
            sb.WriteString("\n")
        }

        // CPU排行
        if len(info.Processes.TopByCPU) > 0 {
            sb.WriteString("进程CPU排行\n")
            headers := []string{"名称", "PID", "CPU(%)"}
            var rows [][]string
            max := len(info.Processes.TopByCPU)
            if max > 10 { max = 10 }
            for i := 0; i < max; i++ {
                p := info.Processes.TopByCPU[i]
                rows = append(rows, []string{p.Name, fmt.Sprintf("%d", p.PID), fmt.Sprintf("%.2f", p.CPUPercent)})
            }
            writeTable(&sb, headers, rows)
            sb.WriteString("\n")
        }
    }

    // 端口占用
    if info.Ports != nil {
        sb.WriteString("端口占用\n")
        headers := []string{"协议", "地址", "端口", "PID", "进程名"}
        var rows [][]string
        max := len(info.Ports.Entries)
        if max > 50 { max = 50 }
        for i := 0; i < max; i++ {
            e := info.Ports.Entries[i]
            ip := e.LocalIP
            if ip == "" { ip = "0.0.0.0" }
            rows = append(rows, []string{strings.ToUpper(e.Protocol), ip, fmt.Sprintf("%d", e.LocalPort), fmt.Sprintf("%d", e.PID), e.ProcessName})
        }
        writeTable(&sb, headers, rows)
        sb.WriteString("\n")
    }

    // 最近活动 - 进程
    if info.Activity != nil && len(info.Activity.RecentProcesses) > 0 {
        headers := []string{"时间", "进程名", "PID"}
        rows := [][]string{}
        max := len(info.Activity.RecentProcesses)
        if max > 15 { max = 15 }
        for i := 0; i < max; i++ {
            p := info.Activity.RecentProcesses[i]
            ts := time.UnixMilli(p.CreateTime).Format("2006-01-02 15:04:05")
            name := p.Name
            if name == "" { name = "(未知)" }
            rows = append(rows, []string{ts, name, fmt.Sprintf("%d", p.PID)})
        }
        writeTable(&sb, headers, rows)
        sb.WriteString("\n")
    }

    // 最近活动 - 文件
    if info.Activity != nil && len(info.Activity.RecentFiles) > 0 {
        headers := []string{"时间", "文件"}
        rows := [][]string{}
        max := len(info.Activity.RecentFiles)
        if max > 15 { max = 15 }
        for i := 0; i < max; i++ {
            f := info.Activity.RecentFiles[i]
            ts := f.OpenedTime.Format("2006-01-02 15:04:05")
            disp := f.DisplayName
            if disp == "" { disp = f.Path }
            rows = append(rows, []string{ts, disp})
        }
        writeTable(&sb, headers, rows)
        sb.WriteString("\n")
    }

    return sb.String()
}

// writeTable 将 headers 与 rows 以简单 ASCII 表格输出
func writeTable(sb *strings.Builder, headers []string, rows [][]string) {
    // 计算列宽（按 rune 计数）
    colCount := len(headers)
    widths := make([]int, colCount)
    for i := 0; i < colCount; i++ {
        widths[i] = utf8.RuneCountInString(headers[i])
    }
    for _, row := range rows {
        for i := 0; i < colCount && i < len(row); i++ {
            l := utf8.RuneCountInString(row[i])
            if l > widths[i] {
                widths[i] = l
            }
        }
    }
    // 留出左右空格
    for i := range widths { widths[i] += 2 }

    // 分隔线
    writeSep := func() {
        sb.WriteString("+")
        for i := 0; i < colCount; i++ {
            sb.WriteString(strings.Repeat("-", widths[i]))
            sb.WriteString("+")
        }
        sb.WriteString("\n")
    }

    // 输出表头
    writeSep()
    sb.WriteString("|")
    for i := 0; i < colCount; i++ {
        sb.WriteString(pad(headers[i], widths[i]))
        sb.WriteString("|")
    }
    sb.WriteString("\n")
    writeSep()

    // 输出内容
    for _, row := range rows {
        sb.WriteString("|")
        for i := 0; i < colCount; i++ {
            cell := ""
            if i < len(row) { cell = row[i] }
            sb.WriteString(pad(cell, widths[i]))
            sb.WriteString("|")
        }
        sb.WriteString("\n")
    }
    writeSep()
}

// pad 在左侧加空格，右侧补齐到宽度
func pad(s string, width int) string {
    // 左侧一个空格，右侧剩余填充
    r := utf8.RuneCountInString(s)
    if r+1 > width { // truncate
        return " " + s
    }
    return " " + s + strings.Repeat(" ", width-1-r)
}